package com.libinshen.wxpay.common.util.wxUtils;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashMap;
import java.util.Map;


/***
 *该方法是微信小程序提取的公共方法
 * 参考一下连接：
 *  https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
 *
 * 注意事项：
 *      1：会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全，开发者服务器不应该把会话密钥下发到小程序，也不应该对外提供这个密钥。
 *      2：临时登录凭证 code 只能使用一次
 */
public class WxMiniLoginUtils {

    private static String accessToken = "";
    private static String expiresTime = "";

    private static String openid = "";
    private static String sessionKey = "";

    private static String getPhoneNumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";
    //获取sessionkey和 openId
    private static String getOpenIdUrl = "https://api.weixin.qq.com/sns/jscode2session";
    //获取accessToken的Url
    private static String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";

    @Value("miniapp.configs.appid")
    private static String appId;

    @Value("miniapp.configs.secret")
    private static String appSecret;


    /***
     * 获取accesstoken 参考
     *  https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
     *      1：token有效期为7200s 2个小时
     *      2：
     *  获取accesstoken
     *
     * @return
     */
    public static String getAccessToken() {
        StringBuilder url = new StringBuilder();
        url.append(getAccessTokenUrl)
                .append("?appid=").append(appId)
                .append("?appSecret=").append(appSecret);

        String result;
        try {
            //向微信服务器发送请求获取accessToken 以及 expires_in
            result = HttpUtil.get(getAccessTokenUrl);
            JSONObject entries = JSONUtil.parseObj(result);
            String expiresTime = entries.get("expires_in").toString();
            accessToken = entries.get("access_token").toString();
            System.out.println("expiresTime 过期时间是：" + expiresTime);
            System.out.println("accessToken 过期时间是：" + accessToken);

        } catch (Exception e) {
            //TODO return CommonResult.error().setMessage("验证码错误");
        }
        return accessToken;
    }

    /**
     * get session_key and openid by code
     *
     * @param code
     * @return
     */
    public static Map getOpenIdAndsessionKey(String code) {
        Map<String, String> map = new HashMap<>();
        //?appid = APPID & secret = SECRET & js_code = JSCODE & grant_type = authorization_code
        StringBuilder url = new StringBuilder();
        url.append(getOpenIdUrl)
                .append("?appid=").append(appId)
                .append("?appSecret=").append(appSecret)
                .append("?js_code=").append(code)
                .append("?grant_type=").append("authorization_code");

        String result;
        try {
            //向微信服务器发送请求获取accessToken 以及 openid
            result = HttpUtil.get(url.toString());
            System.out.println("使用code换取的accessToken为" + result);
            JSONObject entries = JSONUtil.parseObj(result);
            String openid = entries.get("openid").toString();
            String sessionKey = entries.get("session_key").toString();
            map.put("openid", openid);
            openid = openid;
            map.put("session_key", sessionKey);
            sessionKey = sessionKey;
        } catch (Exception e) {
            //TODO return CommonResult.error().setMessage("验证码错误");
        }
        return map;
    }

    /***
     * https://api.weixin.qq.com/wxa/checksession?access_token=OsAoOMw4niuuVbfSxxxxxxxxxxxxxxxxxxx&signature=fefce01bfba4670c85b228e6ca2b493c90971e7c442f54fc448662eb7cd72509&openid=oGZUI0egBJY1zhBYw2KhdUfwVJJE&sig_method=hmac_sha256
     * 检查登录态
     */
    public static void checkSessionKey() {
        StringBuilder url = new StringBuilder();
        url.append("https://api.weixin.qq.com/wxa/checksession")
                .append("?access_token=").append(accessToken)
                .append("&openid=").append(openid)
                //.append("&signature=").append(hmac_sha256(session_key, "")) TODO
                .append("&sig_method=").append("hmac_sha256");

        String result;
        try {
            result = HttpUtil.get(url.toString());
            JSONObject entries = JSONUtil.parseObj(result);
            String errcode = entries.get("errcode").toString();
            if (errcode == "0") {
                //正常的
            } else {

            }
        } catch (Exception e) {
            //TODO return CommonResult.error().setMessage("验证码错误");
        }
    }


    /***
     *重置登录态
     */
    public static void resetUserSessionKey() {
        //https://api.weixin.qq.com/wxa/resetusersessionkey?access_token=ACCESS_TOKEN
        StringBuilder url = new StringBuilder();
        url.append("https://api.weixin.qq.com/wxa/resetusersessionkey")
                .append("?access_token").append(accessToken)
                .append("&openid=").append(openid)
                .append("&signature=").append(openid)//todo
                .append("&sig_method=").append("hmac_sha256");

        String result;
        try {
            result = HttpUtil.get(url.toString());
            JSONObject entries = JSONUtil.parseObj(result);
            String errcode = entries.get("errcode").toString();
            if (errcode == "0") {
                //修改成功将sesion_key存储在redis或者数据库中
            }
        } catch (Exception e) {

        }
    }

    /**
     * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
     * 如何使用 Hutool工具包中的HttpUtil.post()发送请求： 参考
     * https://blog.csdn.net/weixin_42812986/article/details/122999052
     *
     * @return
     */
    public static String getPhoneNumber(String code) {
        StringBuilder url = new StringBuilder()
                .append(getPhoneNumberUrl)
                .append("?access_token=").append(accessToken);

        //构建post请求的体
        JSONObject param = JSONUtil.createObj();
        param.put("code", code);

        String result = HttpUtil.post(url.toString(), param.toString());
        JSONObject entries = JSONUtil.parseObj(result);
        JSONObject phone_info = JSONUtil.parseObj(entries.get("phone_info"));
        String phoneNumber = phone_info.get("phoneNumber").toString();
        return phoneNumber;
    }
}
